package cn.springcloud.fix.common.core.filter;

import com.google.common.collect.Lists;

import java.util.List;

public class FilterChainManager implements IFilterChain {

    private final List<IFilter> filters = Lists.newArrayList();

    public synchronized FilterChainManager addFilter(IFilter filter) {
        int i = 0;
        while (i < this.filters.size()) {
            IFilter currentValue = this.filters.get(i);
            if (currentValue.getFilterName().equals(filter.getFilterName())) {
                break;
            }
            if (filter.getOrder() >= currentValue.getOrder() && i < this.filters.size()) {
                i++;
            } else {
                this.filters.add(i, filter);
                break;
            }
        }
        if (i == this.filters.size()) {
            this.filters.add(i, filter);
        }
        return this;
    }

    @Override
    public void doFilter(IConfigRequest request, IConfigResponse response) throws Exception {
        new VirtualFilterChain(this.filters).doFilter(request, response);
    }

    private static class VirtualFilterChain implements IFilterChain {

        private final List<? extends IFilter> additionalFilters;

        private int currentPosition = 0;

        VirtualFilterChain(List<? extends IFilter> additionalFilters) {
            this.additionalFilters = additionalFilters;
        }

        @Override
        public void doFilter(final IConfigRequest request, final IConfigResponse response) throws Exception {
            if (this.currentPosition != this.additionalFilters.size()) {
                this.currentPosition++;
                IFilter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
                nextFilter.doFilter(request, response, this);
            }
        }
    }
}
